package cn.bfay.lion.rest.service.impl;

import com.google.common.base.Joiner;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import cn.bfay.cache.redis.RedisKeyBuilder;
import cn.bfay.cache.redis.RedisTime;
import cn.bfay.cache.redis.RedisUtils;
import cn.bfay.lion.rest.service.BaseService;
import cn.bfay.lion.rest.client.rsp.ProductInfoRsp;
import cn.bfay.lion.rest.entity.UserProduct;
import cn.bfay.lion.rest.entity.WechatUser;
import cn.bfay.lion.rest.error.RestBusinessError;
import cn.bfay.lion.rest.manager.JingdongManager;
import cn.bfay.lion.rest.mapper.UserProductMapper;
import cn.bfay.lion.rest.mapper.WechatUserMapper;
import cn.bfay.lion.rest.model.UserSession;
import cn.bfay.lion.rest.param.WechatLoginParam;
import cn.bfay.lion.rest.redis.RedisKeyTemplate;
import cn.bfay.lion.rest.service.UserService;
import cn.bfay.lion.rest.vo.UserVo;
import cn.bfay.lion.rest.vo.UserWatchVo;
import cn.bfay.lion.util.StringUtils;
import cn.bfay.web.exception.BizException;
import cn.bfay.web.util.WebUtils;
import cn.bfay.wechat.WechatCoreUtil;
import cn.bfay.wechat.model.WechatPageAccessToken;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

/**
 * UserServiceImpl.
 *
 * @author wangjiannan
 */
@Slf4j
@RequiredArgsConstructor
@Service
public class UserServiceImpl extends BaseService implements UserService {
    //private final HttpServletRequest request;
    private final HttpServletResponse response;

    private final WechatCoreUtil wechatCoreUtil;

    private final WechatUserMapper wechatUserMapper;

    private final UserProductMapper userProductMapper;

    private final JingdongManager jingdongManager;

    @Override
    public void wechatLogin(WechatLoginParam wechatLoginParam) {
        WechatPageAccessToken wechatPageAccessToken = wechatCoreUtil.getPageAccessToken(wechatLoginParam.getCode());
        String openid = wechatPageAccessToken.getOpenid();
        createSessionAndSetCookie(openid);
    }

    private void createSessionAndSetCookie(String openid) {
        UserSession userSession = UserSession.builder().openid(openid).accessToken(StringUtils.getUUId()).build();
        String redisKey = RedisKeyBuilder.generateRedisKey(RedisKeyTemplate.SESSION_TEMPLATE, openid);
        RedisUtils.setValue(redisKey, userSession, RedisTime.DAY);

        WebUtils.setCookie(response, "openid", openid, 60 * 60 * 12);
        WebUtils.setCookie(response, "accessToken", userSession.getAccessToken(), 60 * 60 * 12);
    }

    @Override
    public void checkAdmin() {
        if (!"o1Trh0o7NowjfJcOXRfjZ4KdOWis".equals(getOpenid())) {
            throw new BizException(RestBusinessError.NOT_ADMIN);
        }
    }

    @Override
    public List<UserVo> getWechatUser() {
        List<UserVo> userVos = new ArrayList<>();
        if (!"o1Trh0o7NowjfJcOXRfjZ4KdOWis".equals(getOpenid())) {
            return userVos;
        }
        List<WechatUser> wechatUsers = wechatUserMapper.selectList(null);
        wechatUsers.forEach(wechatUser -> {
            UserVo userVo = new UserVo();
            userVo.setOpenid(wechatUser.getOpenid());
            userVo.setNickname(wechatUser.getNickname());
            if (1 == wechatUser.getState()) {
                userVo.setStateDesc("已关注");
            } else {
                userVo.setStateDesc("未关注");
            }
            userVos.add(userVo);
        });
        return userVos;
    }

    @Override
    public List<UserWatchVo> getUserWatch(String openid) {
        List<UserWatchVo> userWatchVos = new ArrayList<>();
        if (!"o1Trh0o7NowjfJcOXRfjZ4KdOWis".equals(getOpenid())) {
            return userWatchVos;
        }

        List<UserProduct> userProductList = userProductMapper.selectList(new QueryWrapper<UserProduct>().lambda()
            .eq(UserProduct::getOpenid, openid)
            .eq(UserProduct::getMark, (byte) 1)
            .orderByDesc(UserProduct::getUpdateTime));
        if (CollectionUtils.isEmpty(userProductList)) {
            return userWatchVos;
        }

        String skuids =
            Joiner.on(",").join(userProductList.stream().map(UserProduct::getSkuid).collect(Collectors.toList()));
        List<ProductInfoRsp> productInfoRsps = jingdongManager.getProductInfoBySkuids(skuids);
        List<ProductInfoRsp> productInfoRspsNew = new ArrayList<>();
        for (int i = 0; i < userProductList.size(); i++) {
            for (int j = 0; j < productInfoRsps.size(); j++) {
                if (userProductList.get(i).getSkuid().equals(productInfoRsps.get(j).getSkuid())) {
                    productInfoRspsNew.add(productInfoRsps.get(j));
                    break;
                }
            }
        }
        productInfoRspsNew.forEach(productInfoRsp -> {
            UserWatchVo userWatchVo = new UserWatchVo();
            BeanUtils.copyProperties(productInfoRsp, userWatchVo);
            UserProduct userProduct = userProductList.stream()
                .filter(ug -> ug.getSkuid().equals(productInfoRsp.getSkuid()))
                .collect(Collectors.toList()).get(0);
            userWatchVo.setNoticePrice(userProduct.getNoticePrice());
            userWatchVos.add(userWatchVo);
        });

        return userWatchVos;
    }
}
